#============================================
# if request . method ==
# ' POST' :
# username = request . POST . get( 'username' )
# password = request. POST.get(' password' )
# if ' 金瓶梅’in username:
# back_ _dic[ ' username'] = '不符合社会主义核心价值观'
# if len(password) < 3:
# back_ dic[ 'password'] = '不能太短不好! '
# 无论是post请求还是get请求
# 页面都能够获取到字典只不过get请求来的时候字典值都是空的
# 而post请求来之后字典可能有值
# return render (request, ' ab_ form. html' ,locals())

# <form action="" method="post">
# <p>username :
# < input type= "text'
# name= "username ">
# <span style="color: red">{{ back_ dic. username }}</ span>
# </p>
# <p> password:
# <input type="text" name= ”password">
# <span style="color: red">{{ back_ dic . password } }</ span>
# </p>
# <input type=" submit" class="btn btn-info">
# </ form>

# 1.手动书写前端获取用户数据的html代码    渲染htm1代码
# 2.后端对用户数据进行校验              校验数据
# 3.对不符合要求的数据进行前端提示        展示提示信息
#============================================
# form组件
# 能够完成的事情
# 1.渲染html代码
# 2.校验数据
# 3.展示提示信息
# 为什么数据校验非要去后端不能在前端利用js直接完成呢?
# 数据校验前端可有可无
# 但是后端必须要有!!!
# 因为前端的校验是弱不禁风的你可以直接修改
# 或者利用爬虫程序绕过前端页面直接朝后端提交数据

# 购物网站
# 选取了货物之后会计算一个价格发送给后端如果后端不做价格的校验
# 实际是获取到用户选择的所有商品的主键值
# 然后在后端查询出所有商品的价格再次计算一 遍
# 如果跟前端一致那么完成支付如果不一致直接拒绝
#============================================
# 基本使用
# from django import forms
# class MyForm( forms. Form) :
# # username字符串类型最小3位最大8位
# username = forms . CharField (min_ length=3 , max_ length=8)

# # password字符串类型最小3位最大8位
# password = forms . CharField (min_ length=3 , max_ length=8)

# # emai1字段必须符合邮箱格式 xXx@xx . com
# email = forms . EmailField( )
#============================================
# 数据检验
# 1.测试环境的准备可以自己拷贝代码准备
# 2.其实在pycharm里面已经帮你准备-一个测试环境
# python console
# from app01 import views
# # 1将带校验的数据组织成字典的形式传入即可
# form_obj = views .MyForm({'username' :'jason'，' password':' 123', 'email':'123'})
# # 2判断数据是否合法
# 注意该方法只有在所有的数据全部合法的情况下才会返回True
# form_obj.is_valid()
# False
# # 3查看所有校验通过的数据
# form_obj . cleaned_data
# {'username': ' jason', ' password': ' 123' }
# # 4查看所有不符合校验规则以及不符合的原因
# form_obj.errors
# ! email': [' Enter a valid email address. ' ]
# }
# 5校验数据只校验类中出现的字段多传不影响多传的字段直接忽略
# form_ obj = views . MyForm({ 'username': ' jason'，'password' : ' 123', 'email' : ' 123@qq.com','hobby': 'study'})
# form_ obj.is_ valid()
# True

# # 6校验数据默认情况下类里面所有的字段都必须传值
# form_ obj = views . MyForm( { 'username' : 'jason'，' password' : '123'})
# form_ obj.is_ valid()
# False
# 也就意味着校验数据的时候默认情况下数据可以多传但是绝不可能少传
#============================================
# 渲染标签
# forms组件只会自动帮你渲染获取用户输入的标签(input select radio checkbox)
# def index( request):
# # 1先产生一个空对象
# form_ obj = MyForm( )
# # 2直接将该空对象传递给html页面
# return render (request, ' index.html' ,locals())
# #前端利用空对 象做操作
# <p>第一种渲染方式:代码书写极少，封装程度太高不便于后续的扩展一般情况下只在本地
# 测试使用</p>
# {{ form_ obj.as_ P }}
# {{ form_ obj.as_ ul }}
# {{ form_ obj.as_ _table }}

# <p>第二种渲染方式:可扩展性很强但是需要书写的代码太多- -般情况下不用</p>
# <p>{{ form_ _obj . username .label }}:{{ form _obj . username }}</p>
# <p>{{ form_ _obj . password.label }}:{{ form_ obj. password }}</p>
# <p>{{ form_ obj. email.label }}:{{ form obj.email }}</p>

# <p>第三种渲染方式(推荐使用) :代码书写简单并且扩展性也高</p>
# {% for form in form_ obj %}
# <p>{{ form.label }}:{{ form }}</p>
# {% endfor %}

# label属性默认展示的是类中定义的字段首字母大写的形式
# 也可以自己修改直接给字段对象加1abel属性即可
# username = forms . CharField (min_ length=3 , max_ length=8,label='用户名')
#============================================
# 展示提示信息
# 浏览器会自动帮你校验数据但是前端的校验弱不禁风
# 如何让浏览器不做校验
# <form actibn=method= "post" novalidate>
# def index ( request):
# # 1先产生一个空对象
# form_ obj = MyForm( )
# if request . method == ' POST' :
    # #获取用户数据并且校验
    # 1.数据获取繁琐
    # 2.校验数据需要构造成字典的格式传入才行
    # ps :但是request . POST可以看成就是一一个字典
    # # 3.校验数据
    # form _obj = MyForm( request. POST)
    # # 4.判断数据是否合法
    # if form_ obj.is_valid( ):
        # # 5.如果合法操作数据库存储数据
        # return HttpResponse( 'OK')
    # # 5.不合法有错误
    # #2直接将该空对象传递给html页面(前端自动展示)
# return render (request, ' index. html ' , locals())

# {% for form in form_ obj %}
# <p>
# {{ form.label }}:{{ form }}
# <span style="color: red">{{ form.errors.0 }}</ span>
# </p>
# [% endfor %}

# 1.必备的条件get请 求和post传给html页面对象变量名必须一样
# 2. forms组件当你的数据不合法的情况下会保存你上次的数据让你基于之前的结果进行修改
# 更加的人性化

# #针对错误的提示信息还可以自己自定制
# class MyForm( forms . Form) :
# # username字符串类型最小3位最大8位
# username = forms . CharField(min_ length=3 , max_ 1ength=8, label= '用户名'，
# error_ messages={
# 'min_ length' :'用户名最少3位'，
# 'max_ length' :'用户名最大8位' ,
# ' required' :"用户名不能为空”
# }
# # password字符 串类型最小3位最大8位
# password = forms . CharField (min_ length=3, max_ length=8, label= '密码',required
# error_ messages={
# 'min_ length': '密码最少3位'，
# 'max_ length' : '密码最大8位'，
# ' required' : "密码不能为空”
# }
# # emai1字段必须符合邮箱格式
# xxx@xx. com
# email = forms . EmailField( label='邮箱'，
# error_ messages={
# ' invalid':'邮箱格式不正确'，
# ! required' : "邮箱不能为空"
#============================================
# 钩子函数(HOOK)
# 在特定的节点自动触发完成响应操作
# 钩子函数在forms组件中就类似于第二道关卡，能够让我们自定义校验规则
# 在forms组件中有两类钩子
# 1.局部钩子
# 当你需要给单个字段增加校验规则的时候可以使用
# 2.全局钩子
# 当你需要给多个字段增加校验规则的时候可以使用

#局部钩子
# def cLean_username(self):
    # #获取到用户名
    # username = seLf . cLeaned_data . get( ' username ' )
    # if 666' in username :
        # #提示前端展示错误信息
        # self. add_ error( 'username " e '光喊666是不行滴~ ')
    # #将钩子函数钩去出来数据再放回去
    # return username

#全局钩子
# def cLean(self):
    # password = self . cLeaned data . get( ' password' )
    # confirm_ password = self . cleaned_ data . get ( ' confirm_ password ' )
    # if not confirm_ password == password:
        # seLf . add_ error( ' confirm_ password' 名'两次密码不一致' )
    # #将钩子函数钩出来数据再放回去
    # return seLf . cLeaned data
#============================================
# forms组件其他参数及补充知识点
# label                字段名
# error_ messages   自定义报错信息
# initial              默认值
# required         控制字段是 否必填

# 1.字段没有样式
# 2.针对不同类型的input如何修改
# text
# password
# date
# radio
# checkbox
# widget= forms .widgets . PasswordInput (attrs={ 'class': 'form-control c1 c2'})

#第一道关卡里面还支持正则校验
# from django. core. validators import RegexValidator
# validators=[
# RegexValidator(r'^[0-9]+$'，' 请输入数字' ),
# RegexValidator(r'^159[0-9]+$'，' 数字必须以159开头'),
# ]

# 其他字段参考博客 
#============================================